package sys

/*******************************************************************************
Copyright:cloud
Author:cloudapex@126.com
Version:1.0
Date:2020-06-12
Description: 系统.用户
*******************************************************************************/
import (
	"context"
	"permis/api/api"
	"permis/api/cache"
	"permis/model"

	gpc "gitee.com/cloudapex/protos/comm/pb"
	gpb "gitee.com/cloudapex/protos/permis/pb"

	"gitee.com/cloudapex/ulern/util"
)

/*
 * 描述: 用户列表
 * 方法: Simple
 *********************************************************************/
func (this *Server) UserList(ctx context.Context, req *gpb.UserListReq) (*gpb.UserListRes, error) {
	m := &model.User{
		CoId:  req.CoId,
		Name:  req.Name,
		State: req.State,
	}

	total, items, err := int32(0), []model.User{}, error(nil)

	util.Cast(req.Group == 0,
		func() { total, items, err = this.handUserList(ctx, req, m) },          // 不含用户组查找
		func() { total, items, err = this.handUserListWithGroup(ctx, req, m) }) // 含有用户组查找

	if err != nil {
		return nil, err
	}

	rItems := []*gpb.User{}
	if err := util.Convert(&rItems, items); err != nil {
		return nil, api.ConvertError("", err)
	}
	return &gpb.UserListRes{Total: total, List: rItems}, nil
}
func (this *Server) handUserList(ctx context.Context, req *gpb.UserListReq, m *model.User) (total int32, items []model.User, err error) {
	if err := util.Convert(&m.Sorte, req.Sorte); err != nil {
		return 0, nil, api.ConvertError("", err)
	}
	if err := util.Convert(&m.Pager, req.Pager); err != nil {
		return 0, nil, api.ConvertError("", err)
	}
	return m.Find()
}
func (this *Server) handUserListWithGroup(ctx context.Context, req *gpb.UserListReq, m *model.User) (total int32, items []model.User, err error) {
	mg := model.UserWithUserGroup{
		User:      *m,
		UserGroup: model.UserGroup{GroupId: req.Group},
	}
	if err := util.Convert(&mg.Sorte, req.Sorte); err != nil {
		return 0, nil, api.ConvertError("", err)
	}
	if err := util.Convert(&mg.Pager, req.Pager); err != nil {
		return 0, nil, api.ConvertError("", err)
	}
	return mg.FindUsers()
}

/*
 * 描述: 新增用户
 * 方法: Simple
 *********************************************************************/
func (this *Server) UserAdd(ctx context.Context, req *gpb.UserAddReq) (*gpc.IdResponse, error) {
	m := model.User{
		CoId:  req.CoId,
		Id:    req.Id,
		Name:  req.Name,
		State: req.State,
	}
	if _, err := m.Create(); err != nil {
		return nil, api.DBError("", err)
	}
	return &gpc.IdResponse{Id: m.Id}, nil
}

/*
 * 描述: 编辑用户
 * 方法: Simple
 *********************************************************************/
func (this *Server) UserUpd(ctx context.Context, req *gpb.UserUpdReq) (*gpc.UnResponse, error) {
	m := model.User{
		Id:    req.Id,
		Name:  req.Name,
		State: req.State,
	}
	// 更新记录, 允许后面的几个字段被重置为默认值
	if _, err := m.Update(req.Id); err != nil {
		return nil, api.DBError("", err)
	}

	if m.State == model.EState_Unable {
		util.Goroutine("HandUserRoles", func() { // 删除用户角色缓存
			if err := cache.HandUserRoles([]int64{req.Id}, false, true); err != nil {
				this.Error("UserSta.HandUserRoles err:%v", err)
			}
		})
	}
	return &gpc.UnResponse{}, nil
}

/*
 * 描述: 更改用户状态
 * 方法: Simple
 *********************************************************************/
func (this *Server) UserSta(ctx context.Context, req *gpb.UserStaReq) (*gpc.UnResponse, error) {
	m := model.User{State: req.State}
	if _, err := m.Update(req.Id); err != nil {
		return nil, api.DBError("", err)
	}
	if m.State == model.EState_Unable {
		util.Goroutine("HandUserRoles", func() { // 删除用户角色缓存
			if err := cache.HandUserRoles([]int64{req.Id}, false, true); err != nil {
				this.Error("UserSta.HandUserRoles err:%v", err)
			}
		})
	}
	return &gpc.UnResponse{}, nil
}

/*
 * 描述: 删除用户
 * 方法: Simple
 *********************************************************************/
func (this *Server) UserDel(ctx context.Context, req *gpc.IdRequest) (*gpc.UnResponse, error) {
	eff, err := (&model.User{}).Delete(req.Id)
	if err != nil {
		return nil, api.DBError("", err)
	}
	if eff == 0 {
		return nil, api.FoundError("此用户不存在")
	}

	// util.Goroutine("HandUserRoles", func() { // 删除用户角色缓存
	// 	if err := HandUserRoles(req.Id, true); err != nil {
	// 		this.Error("UserDel.HandUserRoles err:%v", err)
	// 	}
	// })
	return &gpc.UnResponse{}, nil
}

/*
 * 描述: 获取用户的组织角色
 * 方法: Simple
 *********************************************************************/
func (this *Server) UserChoice(ctx context.Context, req *gpc.IdRequest) (*gpb.UserChoiceRes, error) {
	// for role
	rIds, err := (&model.UserRole{UserId: req.Id}).FindIds()
	if err != nil {
		return nil, api.DBError("", err)
	}

	// for group
	gIds, err := (&model.UserGroup{UserId: req.Id}).FindIds()
	if err != nil {
		return nil, api.DBError("", err)
	}

	return &gpb.UserChoiceRes{RIds: rIds, GIds: gIds}, nil
}

/*
 * 描述: 修改用户的组织角色
 * 方法: Simple
 *********************************************************************/
func (this *Server) UserChoose(ctx context.Context, req *gpb.UserChooseReq) (*gpc.UnResponse, error) {
	if has, err := (&model.User{Id: req.Id}).Load(); !has || err != nil {
		return nil, api.DBError("此用户不存在", err)
	}
	if vry, err := (&model.Role{}).VerifyIds(req.RIds); !vry || err != nil {
		return nil, api.DBError("角色验证失败", err)
	}
	if vry, err := (&model.Group{}).VerifyIds(req.GIds); !vry || err != nil {
		return nil, api.DBError("用户组验证失败", err)
	}

	// 更新用户与角色的关联
	mr := model.UserRole{}
	if _, err := mr.Delete(req.Id, 0); err != nil {
		return nil, api.DBError("用户角色操作失败", err)
	}
	if err := mr.Insert(req.Id, req.RIds); err != nil {
		return nil, api.DBError("用户角色更新失败", err)
	}

	// 更新用户与用户组的关联
	mg := model.UserGroup{}
	if _, err := mg.Delete(req.Id, 0); err != nil {
		return nil, api.DBError("用户组操作失败", err)
	}
	if err := mg.Insert(req.Id, req.GIds); err != nil {
		return nil, api.DBError("用户组更新失败", err)
	}

	util.Goroutine("HandUserRoles", func() { // 更新用户角色缓存
		if err := cache.HandUserRoles([]int64{req.Id}, false); err != nil {
			this.Error("UserChoose.HandUserRoles err:%v", err)
		}
	})
	return &gpc.UnResponse{}, nil
}

/*
 * 描述: 获取用户的权限信息
 * 方法: Simple
 *********************************************************************/
func (this *Server) UserPermis(ctx context.Context, req *gpb.UserPermisReq) (*gpb.UserPermisRes, error) {
	if req.UId == 0 && req.Name == "" {
		return nil, api.Error(api.ECode_ParamsErr, "请至少使用一个查询条件")
	}

	mUsr := model.User{Id: req.UId, Name: req.Name}
	if has, err := mUsr.Load(); !has || err != nil {
		return nil, api.DBError("目标不存在", err)
	}

	// 所属用户组
	grups, err := (&model.UserGroupWithGroup{
		model.UserGroup{UserId: mUsr.Id},
		model.Group{Tntyp: model.ETreeNode_Leaf},
	}).FindChains()
	if err != nil {
		return nil, api.DBError("用户组查询失败", err)
	}

	// 拥有的角色
	aIds, err := (&model.UserRole{UserId: mUsr.Id}).FindIds()
	if err != nil {
		return nil, api.DBError("角色Id查询失败", err)
	}
	rIds, err := (&model.UserGroupWithGroupRole{UserGroup: model.UserGroup{UserId: mUsr.Id}}).FindRoleIds()
	if err != nil {
		return nil, api.DBError("组角色Id查询失败", err)
	}

	roles := []model.RoleLable{}
	if len(aIds) > 0 {
		aIds = util.RemoveDuplicate64(append(aIds, rIds...))
		labs, err := (&model.Role{CInIds: aIds}).FindLabs()
		if err != nil {
			return nil, api.DBError("角色查询失败", err)
		}
		roles = labs
	}

	// 拥有的权限
	powers := []model.PowerChain{}
	if len(aIds) > 0 {
		chains, err := (&model.RolePowerWithPower{RolePower: model.RolePower{CInRIds: aIds}}).FindChains(model.EPower_Func, model.EPower_Data)
		if err != nil {
			return nil, api.DBError("权限查询失败", err)
		}
		powers = chains
	}

	res := &gpb.UserPermisRes{}
	if err := util.Convert(&res.Groups, grups); err != nil {
		return nil, api.ConvertError("", err)
	}
	if err := util.Convert(&res.Roles, roles); err != nil {
		return nil, api.ConvertError("", err)
	}
	if err := util.Convert(&res.Powers, powers); err != nil {
		return nil, api.ConvertError("", err)
	}
	return res, nil
}
